package com.learn.micro_mall.common.config;


import com.learn.micro_mall.common.util.PlainResultUtils;
import com.learn.micro_mall.service.response.BaseResponse;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.lang.reflect.Method;

@Slf4j
@Aspect
@Component
public class LogAspect {
    //    定义切点就是定义执行的条件execution：用于匹配子表达式，表示哪些下面的包定义为切点
    @Pointcut("execution(* com.learn.micro_mall.service.api.*.*.*(..))")
    public void executeService() {
    }

    //在方法执行前执行的方法
    @Before("executeService()")
    public void before(JoinPoint joinPoint) throws IOException {
        // 接收到请求，记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        // 获取请求的request
        HttpServletRequest request = attributes.getRequest();
        // 获取所有请求的参数，封装为map对象
        // Map<String,Object> parameterMap = getParameterMap(request);
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        // 获取被拦截的方法
        Method method = methodSignature.getMethod();
        // 获取被拦截的方法名
        String methodName = method.getName();
        log.info("AOP begin ,请求开始方法  :{}", method.getDeclaringClass() + "." + methodName + "()");
        // 获取所有请求参数key和value
        log.info("接收到请求:{}", request);

    }

    @Around("executeService()")
    public Object serviceAOP(ProceedingJoinPoint pjp) throws Throwable {

        Object result = null;
        try {
            result =  pjp.proceed();
        } catch (Exception e) {// controller类抛出的异常在这边捕获
            // 接收到请求，记录请求内容
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                    .getRequestAttributes();
            // 获取请求的request
            HttpServletRequest request = attributes.getRequest();
            // 获取所有请求的参数，封装为map对象
            // Map<String,Object> parameterMap = getParameterMap(request);
            MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
            // 获取被拦截的方法
            Method method = methodSignature.getMethod();
            // 获取被拦截的方法名
            String methodName = method.getName();
            // 获取所有请求参数key和value
            log.error("该接口:{} 报错了",methodName);
            log.error("错误信息 = {}", e);
            log.error("请求url = {}", request.getRequestURL().toString());

            log.error("请求方法requestMethod = {}", request.getMethod());
            log.error("请求资源uri = {}", request.getRequestURI());
            result = PlainResultUtils.fail(e.getMessage());
        }
        return result;
    }
}